package com.blue.alipay.utils.ssl;

import com.google.common.collect.Maps;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.Map;

/**
 * 构造SSLConnectionSocketFactory
 * @author chenjiusheng
 * @since 2016年8月29日 下午3:28:28
 */
public class SSLConSocketFactory {

	private static final Logger logger = LoggerFactory.getLogger(SSLConSocketFactory.class);

	private volatile static Map<String, SSLConnectionSocketFactory> sslFactory = Maps.newHashMap();

	private static SSLConnectionSocketFactory buidSSLConSocketFactory(String certPath, String keyPassword) {
		FileInputStream instream = null;
		KeyStore keyStore = null;
		try {
			keyStore = KeyStore.getInstance("PKCS12");
			instream = new FileInputStream(new File(certPath));// 退款证书的路径
			keyStore.load(instream, keyPassword.toCharArray());
			instream.close();
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, keyPassword.toCharArray()).build();
			return new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			if (instream != null) {
				try {
					instream.close();
				} catch (IOException e) {
					logger.error("", e);
				}
			}
		}
		return null;
	}

	public static SSLConnectionSocketFactory get(String certPath, String keyPassword) {
		if(!sslFactory.containsKey(certPath)) {
			synchronized (SSLConSocketFactory.class) {
				if(!sslFactory.containsKey(certPath)) {
					SSLConnectionSocketFactory sslConnectionSocketFactory = buidSSLConSocketFactory(certPath, keyPassword);
					if (sslConnectionSocketFactory != null) {
						sslFactory.put(certPath, sslConnectionSocketFactory);
					} else {
						logger.error("buidSSLConSocketFactory error. certPath:{}", certPath);
						return null;
					}
				}
			}
		}
		return sslFactory.get(certPath);
	}
}
